use std::{path::Path, sync::{Arc, Mutex}};
use crate::{
    error::ServerError, prelude::now_str, protocol::{data_schema::DataTrait, type_schema::TypeSchema}, tasks::task::Task
};

#[derive(Debug, serde::Serialize)]
pub struct TaskFileMeta<'out> {
    pub workflow_id: Option<u16>,
    pub id: &'out str,
    pub remote_id: &'out str,
    pub service_addr: &'out str,
    pub service_name: &'out str,
    pub name: &'out str,
    pub input_type: &'out TypeSchema,
    pub output_type: &'out TypeSchema,
    pub status: crate::protocol::task::TaskStatus,
    pub created_at: u64,
    pub completed_at: Option<u64>,
    pub error_message: Option<&'out str>,
    pub progress_percentage: f64,
    pub log_file_name: Option<&'out str>,
    pub result_sender_addr: &'out str,
    pub terminate_flag: bool, // 手动终止
    pub end_flag: bool, // 任务结束
    pub session_key: &'out str
}

impl<'out> TaskFileMeta<'out> {
    pub fn from_task(task: &'out Task) -> Self {
        Self {
            workflow_id: task.workflow_id,
            id: &task.id,
            remote_id: &task.remote_id,
            service_addr: &task.service_addr,
            service_name: &task.service_name,
            name: &task.name,
            input_type: &task.input_type,
            output_type: &task.output_type,
            status: task.status,
            created_at: task.created_at,
            completed_at: task.completed_at,
            error_message: task.error_message.as_deref(),
            progress_percentage: task.progress_percentage,
            log_file_name: task.log_file_name.as_deref(),
            result_sender_addr: &task.result_sender_addr,
            terminate_flag: *task.terminate_flag.lock().unwrap(),
            end_flag: *task.end_flag.lock().unwrap(),
            session_key: &task.session_key,
        }
    }
}

pub struct TaskFileLogger {
    base_dir: String,
}

impl TaskFileLogger {
    pub fn new() -> Self {
        Self { base_dir: "./edp_files".to_string() }
    }
    pub fn save_task_result(&self, task: &Task) -> Result<(), ServerError> {
        let task_name = format!("{}-{}", task.service_name, task.name);
        let task_fullname = format!("{}-{}", task_name, now_str());
        let task_dir = format!("{}/{}/{}", self.base_dir, task_name, now_str());
        let task_dir = Path::new(&task_dir);
        if !task_dir.exists() {
            std::fs::create_dir_all(task_dir).map_err(|e| ServerError::LogFileError(e.to_string()))?;
        }
        let meta_file = task_dir.join("meta.json");
        let meta_str = serde_json::to_string_pretty(&TaskFileMeta::from_task(task)).map_err(|e| ServerError::LogFileError(e.to_string()))?;
        std::fs::write(meta_file, meta_str).map_err(|e| ServerError::LogFileError(e.to_string()))?;
        let task_file = task_dir.join("result.json");
        if let Some(result) = &task.result {
            if result.is_empty() {
                println!("任务结果为空，不保存: {}", task_fullname);
            } else {
                let json_str = serde_json::to_string_pretty(&result.to_json_less()).map_err(|e| ServerError::LogFileError(e.to_string()))?;
                std::fs::write(task_file, json_str).map_err(|e| ServerError::LogFileError(e.to_string()))?;
                println!("任务结果保存成功: {}", task_fullname);
            }
        } else {
            println!("任务无结果: {}", task_fullname);
        }
        Ok(())
    }
}